from flask import request,jsonify,current_app
from info import db,constants

from info.models import House, Order, Area, Facility
from info.utils.commons import login_required,g
from info.utils.response_code import RET
from info.utils.image_storage import storage
from . import profile_blue
from datetime import datetime

# 用户个人中心首页
@profile_blue.route("/user")
@login_required
def user_ihome():
    user = g.user
    if not user:
        return jsonify(errno=RET.LOGINERR,errmsg="用户未登录")
    data = {
        "user":user.to_dict()
    }
    return jsonify(errno=RET.OK, errmsg="操作成功",data=data)

# 修改用户名
@profile_blue.route("/user/name",methods=["POST"])
@login_required
def change_name():
    user = g.user
    if not user:
        return jsonify(errno=RET.LOGINERR,errmsg="用户未登录")
    name = request.json.get("name")
    if not name:
        return jsonify(errno=RET.PARAMERR,errmsg="参数缺失")
    user.name = name
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="保存数据失败")
    return jsonify(errno=RET.OK,errmsg="修改用户名成功")

# 上传头像
@profile_blue.route("/user/avatar",methods=["POST"])
@login_required
def change_avatar():
    user = g.user
    if not user:
        return jsonify(errno=RET.LOGINERR, errmsg="用户未登录")
    avatar = request.files.get("avatar")
    if not avatar:
        return jsonify(errno=RET.PARAMERR,errmsg="参数错误")
    try:
        avatar_data = avatar.read()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg="参数类型错误")
    try:
        avatar_name = storage(avatar_data)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg="上传图片异常")
    user.avatar_url = avatar_name
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="保存数据失败")
    avatar_url = constants.QINIU_DOMIN_PREFIX + avatar_name
    data = {
        "avatar_url":avatar_url
    }
    return jsonify(errno=RET.OK,errmsg="修改头像成功",data=data)

# 实名认证
@profile_blue.route("/user/auth",methods=["GET","POST"])
@login_required
def user_auth():
    user = g.user
    if not user:
        return jsonify(errno=RET.LOGINERR, errmsg="用户未登录")
    if request.method == "GET":
        data = {
            "real_name":user.real_name,
            "id_card":user.id_card
        }
        return jsonify(errno=RET.OK,errmsg="ok",data=data)
    real_name = request.json.get("real_name")
    id_card = request.json.get("id_card")
    if not all([real_name,id_card]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数缺失")
    user.real_name = real_name
    user.id_card = id_card
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="保存数据失败")
    return jsonify(errno=RET.OK,errmsg="成功")

@profile_blue.route('/user/houses', methods=['GET'])
@login_required
def get_user_houses():
    """
    我的房源
    1.判断用户是否登录
    2.从数据库查找房源数据
    3.按时间倒序显示用户发布房源信息
    4.返回数据

    :return:
    """

    user = g.user
    # 判断用户是否登录
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    user_id = user.id

    try:
        # user = User.query.get(user_id)
        # houses = user.houses
        houses = House.query.filter_by(user_id=user_id)
        # 测试数据
        # houses = House.query.filter_by(user_id=7)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="获取数据失败")

    # 将查询到的房屋信息转换为字典存放到列表中
    houses_list = []

    if houses:
        for house in houses:
            houses_list.append(house.to_basic_dict())

    return jsonify(errno=RET.OK, errmsg="OK", data=houses_list)


@profile_blue.route('/houses', methods=['POST'])
@login_required
def set_new_house():
    """
    发布新房源
    1.获取参数 title, price, area_id, address, room_count, acreage,unit, capacity, beds, deposit, min_days, max_days
    2.检查参数有效性
    3.转换参数类型
    4.判断参数是否合法
    5.存入数据库
    6.返回数据

    前端发送过来的json数据
    {
        "title":"",
        "price":"",
        "area_id":"1",
        "address":"",
        "room_count":"",
        "acreage":"",
        "unit":"",
        "capacity":"",
        "beds":"",
        "deposit":"",
        "min_days":"",
        "max_days":"",
        "facility":["7","8"]
    }
    """

    # 获取需要获得的信息
    user = g.user
    house_data = request.get_json()
    title = house_data.get("title")  # 房屋名称标题
    price = house_data.get("price")  # 房屋单价
    area_id = house_data.get("area_id")  # 房屋所属城区的编号
    address = house_data.get("address")  # 房屋地址
    room_count = house_data.get("room_count")  # 房屋包含的房间数目
    acreage = house_data.get("acreage")  # 房屋面积
    unit = house_data.get("unit")  # 房屋布局（几室几厅)
    capacity = house_data.get("capacity")  # 房屋容纳人数
    beds = house_data.get("beds")  # 房屋卧床数目
    deposit = house_data.get("deposit")  # 押金
    min_days = house_data.get("min_days")  # 最小入住天数
    max_days = house_data.get("max_days")  # 最大入住天数

    # 检验参数
    if not all([title, price, area_id, address, room_count, acreage,
                unit, capacity, beds, deposit, min_days, max_days]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    # 将数据进行分析处理并存储到数据库中
    # 判断金额是否完全正确
    try:
        price = int(float(price) * 100)
        deposit = int(float(deposit) * 100)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg='参数有误')

    # 判断城区id是否存在
    try:
        area = Area.query.get(area_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库异常')

    if area is None:
        return jsonify(errno=RET.NODATA, errmsg='未获取到城区信息')

    # 保存房屋信息
    house = House()
    house.user_id = user.id
    house.area_id = area_id,
    house.title = title,
    house.price = price,
    house.address = address,
    house.room_count = room_count,
    house.acreage = acreage,
    house.unit = unit,
    house.capacity = capacity,
    house.beds = beds,
    house.deposit = deposit,
    house.min_days = min_days,
    house.max_days = max_days

    # 处理房屋的设施信息
    facility_ids = house_data.get('facility')

    # 如果用户勾选了设施信息，再保存数据库
    if facility_ids:
        try:
            facilities = Facility.query.filter(Facility.id.in_(facility_ids)).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg='数据库错误')
        if facilities:
            house.facilities = facilities
            db.session.add(house)

    # 进行数据库提交操作
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存数据库失败')

    # 保存数据成功
    return jsonify(errno=RET.OK, errmsg='OK', data={'house_id': house.id})

# 上传房源图片
@profile_blue.route("/houses/<int:house_id>/image",methods=["POST"])
@login_required
def houses_image(house_id):
    user = g.user
    if not user:
        return jsonify('/')
    houses_image = request.files.get("house_image")
    if not all([houses_image,house_id]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数缺失")
    try:
        house = House.query.filter_by(house_id=house_id).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询数据库错误")
    if not house:
        return jsonify(errno=RET.NODATA,errmsg="无房屋数据")
    try:
        houses_image_data = houses_image.read()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg="参数类型错误")
    try:
        houses_image_name = storage(houses_image_data)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg="上传房源图片失败")
    house.images = houses_image_name
    house_image = HouseImage()
    house_image.house_id = house_id
    house_image.url = image_name
    try:
        db.session.add([house,houses_image])
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="保存数据异常")
    data = {
        "url":constants.QINIU_DOMIN_PREFIX + houses_image_name
    }
    return jsonify(errno=RET.OK,errmsg="上传房源图片成功",data=data)


###########################################################################################
# 添加订单
@profile_blue.route('/orders',methods=['POST'])
@login_required
def add_orders():

    """

    1 请求参数  house_id  start_data 开始日期  end_data 结束时间

    :return:
    """
    # 判断用户是否登陆
    user = g.user
    if not user:
        return jsonify('/')
    # 获取参数
    house_id = request.json.get('house_id')
    start_data = request.json.get('start_data')
    end_data = request.json.get('end_data')
    #  检查参数的完整性
    if not all([house_id,start_data,end_data]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数缺失')
    # 校验house_id 格式

    try:
        house_id = int(house_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg='参数格式错误')
    # 查询数据库 获取房屋信息
    try:
        start_data = datetime.strptime(start_data,'%Y-%m-%d')
        end_data = datetime.strptime(end_data,'%Y-%m-%d')
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg='参数格式错误')
    try:
        house = House.query.get(house_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='数据库查询失败')
    if not house:
        return jsonify(errno=RET.NODATA,errmsg='查询房屋信息失败')

    # 查询房屋的所有订单
    orders = house.orders
    if orders:
        for order in orders:
            if start_data < order.end_date and end_data > order.begin_date:
                return jsonify(errno=RET.DATAEXIST,errmsg='房屋该时间段已被预定')

    # 构建模型类保存订单到数据库
    day = (end_data - start_data).days
    new_order = Order()
    new_order.user_id = user.id
    new_order.house_id = house_id
    new_order.begin_date = start_data
    new_order.end_date = end_data
    new_order.days = day
    new_order.house_price = house.price
    new_order.amount = day*house.price
    new_order.status = 'WAIT_ACCEPT'

    try:
        db.session.add(new_order)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollbask()
        return jsonify(errno=RET.DBERR,errmsg='数据库保存失败')

    data = {
        'order_id':new_order.id
    }

    return jsonify(errno=RET.OK,errmsg='OK',data=data)


# 订单列表接口
@profile_blue.route('/orders')
@login_required
def get_order():
    """
    获取订单列表
    :return:
    """
    # 尝试获取用户信息
    user  = g.user
    if not user:
        return redirect('/api/v1.0/session')

    # 获取参数,args传参
    role  = request.args.get('role')
    if not role:
        return jsonify(errno=RET.NODATA, errmsg='参数缺失')
    if role not in ['custom','landlord']:
        return jsonify(errno =RET.PARAMERR,errmsg = '参数类型错误')
    # 如果是房客角色
    if role =='custom':
        # 查询所有的订单
        try:
            orders = Order.query.filter(Order.user_id == user.id).order_by(Order.create_time.desc()).all()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno = RET.DBERR,errmsg = '查询顾客订单失败')
        if not orders:
            return jsonify(errno = RET.NODATA,errmsg = '该用户没有订单')
        order_list = []
        for order in orders:
            order_list.append(order.to_dict())
    # 角色是房东
    else:
        # 获取房东的房屋信息
        houses = user.houses
        if not houses:
            return jsonify(errno = RET.NODATA,errmsg = '该用户没有房屋订单')
        # 遍历
        # 构造house_id_list
        house_id_list = [house.id for house in houses]
        order_list = []
        # 根据房屋id查询订单
        try:
            orders = Order.query.filter(Order.house_id.in_(house_id_list)).order_by(Order.create_time.desc())
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno = RET.DBERR,errmsg = '查询房东订单失败')
        if orders:
            for order in orders:
                order_list.append(order.to_dict())
        else:
            return jsonify(errno = RET.NODATA,errmsg = '该用户没有房屋订单')

    data = {
        'orders':order_list
    }

    return jsonify(errno = RET.OK,errmsg = 'OK',data = data)

# 接单和拒单的接口
@profile_blue.route('/orders',methods = ['PUT'])
@login_required
def order_action():
    """
    接单或者拒单的接口
    :return:
    """
    pass
    # 尝试获取用户信息
    user = g.user
    if not user:
        return redirect('/api/v1.0/session')
    # 获取参数
    action = request.json.get('action')
    order_id = request.json.get('order_id')
    reason = request.json.get('reason')

    if not all([action,order_id]):
        return jsonify(errno = RET.PARAMERR,errmsg = '参数缺失')
    # 校验参数类型
    if action not in ['accept','reject']:
        return jsonify(errno = RET.PARAMERR,errmsg = '参数类型错误')
    try:
        order_id = int(order_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.PARAMERR,errmsg = '参数类型错误')
    # 查询数据库，看订单是否存在
    try:
        order = Order.query.get(order_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR,errmsg = '查询订单错误')
    if not order:
        return jsonify(errno=RET.NODATA, errmsg='没有订单数据')
    # 业务处理
    if action =='accept':
        # 判断订单类型为待接单
        if order.status != 'WAIT_ACCEPT':
            return jsonify(errno = RET.DATAERR,errmsg = '订单状态错误')
        order.status = 'WAIT_COMMENT'
        # 提交数据库
        try:
            db.session.add(order)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno = RET.DBERR,errmsg = '数据库保存失败')
    else:
        if order.status != 'WAIT_ACCEPT':
            return jsonify(errno = RET.DATAERR,errmsg = '订单状态错误')
        order.status = 'REJECTED'
        if reason:
            order.comment = reason
        # 提交数据库
        try:
            db.session.add(order)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno=RET.DBERR, errmsg='数据库保存失败')

    return jsonify(errno = RET.OK,errmsg = 'OK')

# 评论订单接口
@profile_blue.route('/orders/comment',methods = ['PUT'])
@login_required
def order_comment():
    """
    订单评论接口
    :return:
    """
    pass
    # 尝试获取用户信息
    user = g.user
    if not user:
        return redirect('/api/v1.0/session')
    # 获取参数
    comment = request.json.get('comment')
    order_id = request.json.get('order_id')
    if not all([comment,order_id]):
        return jsonify(errno = RET.PARAMERR,errmsg = '参数缺失')
    # 校验参数格式
    try:
        order_id = int(order_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.PARAMERR,errmsg = '参数类型错误')
    # 查询数据库，获取订单信息
    try:
        order = Order.query.get(order_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno = RET.DBERR,errmsg = '查询订单失败')
    if not order:
        return jsonify(errno = RET.NODATA,errmsg = '没有该订单信息')
    if order.status != 'WAIT_COMMENT':
        return jsonify(errno=RET.DATAERR, errmsg='订单状态错误')
    order.status = 'COMPLETE'
    order.comment = comment
    # 提交数据库
    try:
        db.session.add(order)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno = RET.DBERR,errmsg = '数据库保存失败')

    return jsonify(errno = RET.OK,errmsg = 'OK')







